import { LogContext } from '../interface/LogContext'
import { Logger } from '../interface/Logger'
import { LoggerLevel } from '../interface/LoggerLevel'

/**
 * 抽象记录器记录实现
 * 实现日志不同日志等级的汇聚
 *
 * @author 冰凝
 * @date 2022/12/10 21:06
 */
export class LoggerImpl implements Logger {
    protected readonly name: string
    protected readonly context: LogContext
    protected readonly debugLevel: LoggerLevel | undefined

    public constructor(name: string, context: LogContext, debugLevel?: LoggerLevel) {
        this.name = name
        this.context = context
        this.debugLevel = debugLevel
    }

    public getName(): string {
        return this.name
    }

    public trace(...args: Array<any>): void {
        this.log(LoggerLevel.TRACE, ...args)
    }

    public debug(...args: Array<any>): void {
        this.log(LoggerLevel.DEBUG, ...args)
    }

    public info(...args: Array<any>): void {
        this.log(LoggerLevel.INFO, ...args)
    }

    public warn(...args: Array<any>): void {
        this.log(LoggerLevel.WARN, ...args)
    }

    public error(...args: Array<any>): void {
        this.log(LoggerLevel.ERROR, ...args)
    }

    public isDebugEnable(): boolean {
        return this.isEnable(LoggerLevel.DEBUG)
    }

    public isErrorEnable(): boolean {
        return this.isEnable(LoggerLevel.ERROR)
    }

    public isInfoEnable(): boolean {
        return this.isEnable(LoggerLevel.INFO)
    }

    public isTraceEnable(): boolean {
        return this.isEnable(LoggerLevel.TRACE)
    }

    public isWarnEnable(): boolean {
        return this.isEnable(LoggerLevel.WARN)
    }

    protected isEnable(level: LoggerLevel): boolean {
        if (this.context.config.enableDebugLevel && this.debugLevel && level >= this.debugLevel) {
            return true
        }
        return this.context.isEnable(this.name, level)
    }

    protected log(level: LoggerLevel, ...args: Array<any>): void {
        if (this.context.config.enableDebugLevel && this.debugLevel && level >= this.debugLevel) {
            this.context.log(this.name, level, ...args)
        } else {
            this.context.log(this.name, level, ...args)
        }
    }

}
